package com.bing.server;

import com.bing.common.Message;
import com.bing.common.MessageType;
import com.bing.common.User;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 服务器消息处理器
 */
public class ServerHandler extends SimpleChannelInboundHandler<Message> {

    /**
     * 所有客户端连接管理
     */
    private static final ChannelGroup CHANNELS = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 在线用户表：用户名 -> Channel
     */
    private static final Map<String, Channel> ONLINE_USERS = new ConcurrentHashMap<>();

    /**
     * 用户管理：用户名 -> 用户对象
     */
    private static final Map<String, User> USER_MAP = new ConcurrentHashMap<>();

    /**
     * Channel和用户名的映射关系：Channel ID -> 用户名
     */
    private static final Map<String, String> CHANNEL_USER_MAP = new ConcurrentHashMap<>();

    // 静态初始化块，创建默认用户
    static {
        // 添加默认用户
        addDefaultUser("test", "123456");
        addDefaultUser("root", "root");
        addDefaultUser("admin", "admin");
        System.out.println("已创建默认用户: test/123456, root/root, admin/admin");
    }

    /**
     * 添加默认用户
     */
    private static void addDefaultUser(String username, String password) {
        User user = new User(username, password);
        user.setId(UUID.randomUUID().toString());
        user.setRegisterTime(new Date().toString());
        USER_MAP.put(username, user);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        CHANNELS.add(ctx.channel());
        System.out.println("客户端连接：" + ctx.channel().remoteAddress());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        CHANNELS.remove(ctx.channel());
        String channelId = ctx.channel().id().asLongText();
        String username = CHANNEL_USER_MAP.get(channelId);

        if (username != null) {
            // 从映射关系中移除
            CHANNEL_USER_MAP.remove(channelId);
            ONLINE_USERS.remove(username);

            // 更新用户状态
            User user = USER_MAP.get(username);
            if (user != null) {
                user.setOnline(false);
            }

            // 广播用户下线消息
            broadcastSystemMessage("用户 " + username + " 已下线，当前在线人数: " + ONLINE_USERS.size());
        }

        System.out.println("客户端断开连接：" + ctx.channel().remoteAddress());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Message msg) {
        MessageType type = msg.getType();
        Channel channel = ctx.channel();

        System.out.println("收到消息类型: " + type + ", 来自: " + channel.remoteAddress());

        try {
            switch (type) {
                case LOGIN_REQUEST:
                    handleLoginRequest(channel, msg);
                    break;
                case REGISTER_REQUEST:
                    handleRegisterRequest(channel, msg);
                    break;
                case CHAT_MESSAGE:
                    handleChatMessage(channel, msg);
                    break;
                case HISTORY_REQUEST:
                    handleHistoryRequest(channel, msg);
                    break;
                case UPDATE_INFO_REQUEST:
                    handleUpdateInfoRequest(channel, msg);
                    break;
                case LOGOUT:
                    handleLogout(channel, msg);
                    break;
                default:
                    System.out.println("未知消息类型: " + type);
                    break;
            }
        } catch (Exception e) {
            System.err.println("处理消息时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 处理登录请求
     */
    private void handleLoginRequest(Channel channel, Message msg) {
        String username = msg.getUsername();
        String password = msg.getPassword();

        System.out.println("登录请求: 用户名=" + username + ", 密码=" + password);

        // 打印当前所有用户
        System.out.println("当前用户列表: " + USER_MAP.keySet());

        Message response = new Message();
        response.setType(MessageType.LOGIN_RESPONSE);

        User user = USER_MAP.get(username);
        if (user != null && user.getPassword().equals(password)) {
            if (ONLINE_USERS.containsKey(username)) {
                // 用户已在线
                response.setContent("false|用户已在线");
                System.out.println("登录失败: 用户 " + username + " 已在线");
            } else {
                // 登录成功
                user.setOnline(true);
                user.setLastLoginTime(new Date());

                // 保存映射关系
                ONLINE_USERS.put(username, channel);
                CHANNEL_USER_MAP.put(channel.id().asLongText(), username);

                response.setContent("true");
                System.out.println("登录成功: 用户 " + username);

                // 广播用户上线消息
                broadcastSystemMessage("用户 " + username + " 已上线，当前在线人数: " + ONLINE_USERS.size());
            }
        } else {
            // 用户不存在或密码错误
            response.setContent("false|用户名或密码错误");
            System.out.println("登录失败: 用户 " + username + " 用户名或密码错误");
        }

        // 发送响应
        try {
            channel.writeAndFlush(response);
            System.out.println("已发送登录响应: " + response.getContent());
        } catch (Exception e) {
            System.err.println("发送登录响应时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 处理注册请求
     */
    private void handleRegisterRequest(Channel channel, Message msg) {
        String username = msg.getUsername();
        String password = msg.getPassword();

        System.out.println("注册请求: 用户名=" + username);

        Message response = new Message();
        response.setType(MessageType.REGISTER_RESPONSE);

        if (USER_MAP.containsKey(username)) {
            response.setContent("false|用户名已存在");
            System.out.println("注册失败: 用户名 " + username + " 已存在");
        } else {
            // 创建用户
            User user = new User(username, password);
            user.setId(UUID.randomUUID().toString());
            user.setRegisterTime(new Date().toString());
            USER_MAP.put(username, user);

            response.setContent("true");
            System.out.println("注册成功: 用户 " + username);
        }

        try {
            channel.writeAndFlush(response);
            System.out.println("已发送注册响应: " + response.getContent());
        } catch (Exception e) {
            System.err.println("发送注册响应时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 处理聊天消息
     */
    private void handleChatMessage(Channel channel, Message msg) {
        String sender = msg.getSender();
        String receiver = msg.getReceiver();
        String content = msg.getContent();
        String channelId = channel.id().asLongText();
        String username = CHANNEL_USER_MAP.get(channelId);

        System.out.println("聊天消息: 发送者=" + sender + ", 接收者=" + receiver + ", 内容=" + content);

        // 验证用户身份
        if (username == null || !username.equals(sender)) {
            // 身份验证失败
            Message response = new Message();
            response.setType(MessageType.SYSTEM_MESSAGE);
            response.setContent("消息发送失败：身份验证失败");
            channel.writeAndFlush(response);
            System.out.println("消息发送失败: 身份验证失败");
            return;
        }

        // 保存消息到用户历史记录
        User user = USER_MAP.get(sender);
        if (user != null) {
            user.addChatMessage(content);
        }

        // 更新发送时间
        msg.setSendTime(new Date());

        if (receiver != null && !receiver.isEmpty()) {
            // 私聊消息
            Channel receiverChannel = ONLINE_USERS.get(receiver);
            if (receiverChannel != null) {
                receiverChannel.writeAndFlush(msg);
                channel.writeAndFlush(msg); // 发送给自己
                System.out.println("私聊消息已发送");
            } else {
                // 接收者不在线
                Message response = new Message();
                response.setType(MessageType.SYSTEM_MESSAGE);
                response.setContent("用户 " + receiver + " 不在线或不存在");
                channel.writeAndFlush(response);
                System.out.println("接收者不在线: " + receiver);
            }
        } else {
            // 广播公共消息
            for (Channel ch : CHANNELS) {
                ch.writeAndFlush(msg);
            }
            System.out.println("公共消息已广播");
        }
    }

    /**
     * 处理历史消息请求
     */
    private void handleHistoryRequest(Channel channel, Message msg) {
        String username = msg.getUsername();
        String channelId = channel.id().asLongText();
        String currentUser = CHANNEL_USER_MAP.get(channelId);

        System.out.println("历史消息请求: 用户=" + username);

        // 验证用户身份
        if (currentUser == null || !currentUser.equals(username)) {
            // 身份验证失败
            Message response = new Message();
            response.setType(MessageType.SYSTEM_MESSAGE);
            response.setContent("获取历史消息失败：身份验证失败");
            channel.writeAndFlush(response);
            System.out.println("获取历史消息失败: 身份验证失败");
            return;
        }

        User user = USER_MAP.get(username);
        if (user != null) {
            List<String> historyText = user.getChatHistory();
            List<Message> historyMessages = new ArrayList<>();

            // 将文本历史消息转为消息对象
            for (String text : historyText) {
                Message historyMsg = new Message();
                historyMsg.setSender(username);
                historyMsg.setContent(text);
                historyMsg.setSendTime(new Date()); // 实际应保存真实时间
                historyMessages.add(historyMsg);
            }

            // 构建响应
            Message response = new Message();
            response.setType(MessageType.HISTORY_RESPONSE);
            response.setHistoryMessages(historyMessages);

            channel.writeAndFlush(response);
            System.out.println("历史消息已发送: " + historyMessages.size() + " 条");
        }
    }

    /**
     * 处理更新用户信息请求
     */
    private void handleUpdateInfoRequest(Channel channel, Message msg) {
        String username = msg.getUsername();
        String newUsername = msg.getReceiver(); // 接收者字段用于存新用户名
        String newPassword = msg.getNewPassword();
        String channelId = channel.id().asLongText();
        String currentUser = CHANNEL_USER_MAP.get(channelId);

        System.out.println("更新用户信息请求: 用户=" + username + ", 新用户名=" + newUsername + ", 新密码="
                + (newPassword != null ? "已设置" : "未设置"));

        // 验证用户身份
        if (currentUser == null || !currentUser.equals(username)) {
            // 身份验证失败
            Message response = new Message();
            response.setType(MessageType.UPDATE_INFO_RESPONSE);
            response.setContent("false|身份验证失败");
            channel.writeAndFlush(response);
            System.out.println("更新用户信息失败: 身份验证失败");
            return;
        }

        User user = USER_MAP.get(username);
        if (user != null) {
            boolean updated = false;
            String responseMsg = "true";

            // 更新用户名
            if (newUsername != null && !newUsername.isEmpty()) {
                if (USER_MAP.containsKey(newUsername) && !newUsername.equals(username)) {
                    // 用户名已存在
                    Message response = new Message();
                    response.setType(MessageType.UPDATE_INFO_RESPONSE);
                    response.setContent("false|用户名已存在");
                    channel.writeAndFlush(response);
                    System.out.println("更新用户信息失败: 用户名已存在");
                    return;
                }

                // 更新映射关系
                USER_MAP.remove(username);
                ONLINE_USERS.remove(username);
                CHANNEL_USER_MAP.put(channelId, newUsername);

                // 更新用户名
                user.updateUsername(newUsername);

                // 更新映射
                USER_MAP.put(newUsername, user);
                ONLINE_USERS.put(newUsername, channel);

                updated = true;
                responseMsg = "用户名已更新为: " + newUsername;
                System.out.println("用户名已更新: " + username + " -> " + newUsername);
            }

            // 更新密码
            if (newPassword != null && !newPassword.isEmpty()) {
                user.updatePassword(newPassword);
                updated = true;
                responseMsg = updated ? "用户名和密码已更新" : "密码已更新";
                System.out.println("密码已更新: 用户=" + (newUsername != null ? newUsername : username));
            }

            if (updated) {
                Message response = new Message();
                response.setType(MessageType.UPDATE_INFO_RESPONSE);
                response.setContent("true|" + responseMsg);
                response.setReceiver(newUsername); // 返回新用户名

                channel.writeAndFlush(response);
            } else {
                Message response = new Message();
                response.setType(MessageType.UPDATE_INFO_RESPONSE);
                response.setContent("false|未提供任何更新信息");

                channel.writeAndFlush(response);
                System.out.println("更新用户信息失败: 未提供任何更新信息");
            }
        }
    }

    /**
     * 处理登出请求
     */
    private void handleLogout(Channel channel, Message msg) {
        String username = msg.getUsername();
        String channelId = channel.id().asLongText();
        String currentUser = CHANNEL_USER_MAP.get(channelId);

        System.out.println("登出请求: 用户=" + username);

        // 验证用户身份
        if (currentUser != null && currentUser.equals(username)) {
            // 从映射关系中移除
            CHANNEL_USER_MAP.remove(channelId);
            ONLINE_USERS.remove(username);

            // 更新用户状态
            User user = USER_MAP.get(username);
            if (user != null) {
                user.setOnline(false);
            }

            // 广播用户下线消息
            broadcastSystemMessage("用户 " + username + " 已下线，当前在线人数: " + ONLINE_USERS.size());
            System.out.println("用户已登出: " + username);
        }
    }

    /**
     * 广播系统消息
     */
    private void broadcastSystemMessage(String content) {
        Message message = new Message();
        message.setType(MessageType.SYSTEM_MESSAGE);
        message.setSender("系统");
        message.setContent(content);
        message.setSendTime(new Date());

        for (Channel channel : CHANNELS) {
            channel.writeAndFlush(message);
        }
        System.out.println("系统消息已广播: " + content);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        System.err.println("ServerHandler异常: " + cause.getMessage());
        cause.printStackTrace();
        ctx.close();
    }
}